package com.example.geohash;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class GeoServiceImpl implements GeoService {

    private final String GEO_KEY = "shops";

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Override
    public Long initGeoInfo(Collection<Shops> shops) {
        GeoOperations<String, String> ops = redisTemplate.opsForGeo();

        Set<RedisGeoCommands.GeoLocation<String>> locations = new HashSet<>();
        shops.forEach(ci -> locations.add(new RedisGeoCommands.GeoLocation<String>(
                ci.getName(), new Point(ci.getLongitude(), ci.getLatitude())
        )));

        return ops.add(GEO_KEY, locations);

    }

    @Override
    public List<Point> getPos(String[] strings) {
        GeoOperations<String, String> ops = redisTemplate.opsForGeo();
        return ops.position(GEO_KEY, strings);
    }

    @Override
    public Distance distanceBTPoints(String var1, String var2, Metric metric) {
        GeoOperations<String, String> ops = redisTemplate.opsForGeo();
        return metric == null ? ops.distance(GEO_KEY, var1, var2) : ops.distance(GEO_KEY, var1, var2, metric);
    }

    @Override
    public GeoResults<RedisGeoCommands.GeoLocation<String>> getPointRadius(Circle within, RedisGeoCommands.GeoRadiusCommandArgs args) {
        GeoOperations<String, String> ops = redisTemplate.opsForGeo();
        return args == null ? ops.radius(GEO_KEY, within) : ops.radius(GEO_KEY, within, args);
    }

    @Override
    public GeoResults<RedisGeoCommands.GeoLocation<String>> getMemberRadius(String member, Distance distance, RedisGeoCommands.GeoRadiusCommandArgs args) {
        GeoOperations<String, String> ops = redisTemplate.opsForGeo();
        return args == null ? ops.radius(GEO_KEY, member, distance) : ops.radius(GEO_KEY, member, distance, args);
    }

    @Override
    public List<String> getGeoHash(String[] cities) {
        GeoOperations<String, String> ops = redisTemplate.opsForGeo();
        return ops.hash(GEO_KEY, cities);
    }
}
